#include "Epoll.h"

Epoll::Epoll()
{
    epollfd_ = epoll_create(1);
    if (epollfd_ == -1)
    {
        printf("epoll_create faild(%d) %s ", errno, strerror(errno));
        exit(-1);
    }
}
Epoll::~Epoll()
{
    close(epollfd_);
}

void Epoll::addFd(int fd, uint32_t op)
{
    struct epoll_event ev;
    ev.data.fd = fd;
    ev.events = op;
    if (epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev) == -1)
    {
        printf("epoll_ctl faild(%d) %s ", errno, strerror(errno));
    }
}

// // 这里有点没理解
// std::vector<epoll_event> Epoll::loop(int timeout)
// {
//     std::vector<epoll_event> evs;
//     // 用一个数组来接受
//     memset(events_, 0, sizeof(events_));
//     int infds = epoll_wait(epollfd_, events_, MAXEVENTNUM, timeout);

//     if (infds < 0)
//     {
//         printf("epoll_wait faild(%d) %s ", errno, strerror(errno));
//         exit(-1);
//     }

//     if(infds==0)
//     {
//         return evs;
//     }

//     for(int i =0 ;i<infds;i++)
//     {
//         evs.push_back(events_[i]);
//     }
//     return evs;
// }
// ch是封装了epoll
void Epoll::updateChannel(Channel *ch)
{
    epoll_event ev;
    ev.events = ch->events();
    ev.data.ptr = ch;

    if (ch->inepoll())
    {
        if (epoll_ctl(epollfd_, EPOLL_CTL_MOD, ch->fd(), &ev) == -1)
        {
            perror("epoll_ctl() failed.\n");
            exit(-1);
        }
    }
    else
    {
        if (epoll_ctl(epollfd_, EPOLL_CTL_ADD, ch->fd(), &ev) == -1)
        {
            perror("epoll_ctl() failed.\n");
            exit(-1);
        }
        ch->setinepoll();
    }
}

std::vector<Channel*> Epoll::loop(int timeout)
{
    std::vector<Channel*> chs;
    memset(events_, 0, sizeof(events_));

    int infds = epoll_wait(epollfd_,events_,MAXEVENTNUM,timeout);

    if(infds<0)
    {
        printf("epoll_wait faild(%d) %s ", errno, strerror(errno));
        exit(-1);
    }

    if(infds==0)
    {
        return chs;
    }

    for(int i =0;i<infds;i++)
    {
        Channel* ch = (Channel*)events_[i].data.ptr;
        ch->setrevents(events_[i].events);
        chs.push_back(ch);
    }

    return chs;

    


}